package nl.sweet.testsweet.gui;

import java.awt.EventQueue;
import java.util.LinkedList;

import javax.swing.JFrame;
import javax.swing.UIManager;

import nl.sweet.testsweet.TestSweetListener;
import nl.sweet.testsweet.TestSweetResult;
import nl.sweet.testsweet.TestSweetTestCase;
import nl.sweet.testsweet.sample.test.SampleTestCase;

public class TestSweetApplication implements TestSweetListener
{
	/** The width of the results window. */
	public static final int RESULTS_WINDOW_WIDTH = 700;

	/** The height of the results window. */
	public static final int RESULTS_WINDOW_HEIGHT = 400;

	/** The frame which displays the result of the tests. */
	private TestSweetFrame _testSweetFrame;

	/** The total time taken. */
	private double _totalTimeTaken;

	/** The list with the results. */
	private LinkedList<TestSweetResult> _testSweetResults;

	private LinkedList<Class< ? extends TestSweetTestCase>> _testClasses;

	/**
	 * Entry point to the Application for the GUI version.
	 * @param args Arguments parsed to the application.
	 */
	public static void main(String[] args)
	{
		JFrame.setDefaultLookAndFeelDecorated(false);

		// Create a linkedlist with the test cases.
		LinkedList<Class< ? extends TestSweetTestCase>> testCases = new LinkedList<Class< ? extends TestSweetTestCase>>();
		testCases.add(SampleTestCase.class);
		testCases.add(SampleTestCase.class);
		testCases.add(SampleTestCase.class);
		testCases.add(SampleTestCase.class);
		testCases.add(SampleTestCase.class);
		testCases.add(SampleTestCase.class);

		new TestSweetApplication(testCases);
	}

	/**
	 * Constructor.
	 */
	public TestSweetApplication(LinkedList<Class< ? extends TestSweetTestCase>> testCases)
	{
		JFrame.setDefaultLookAndFeelDecorated(false);
		try
		{
			UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
		}
		TestSweetSplash splashScreen = new TestSweetSplash();

		_testClasses = testCases;
		_testSweetResults = new LinkedList<TestSweetResult>();

		// Create the frame.
		_testSweetFrame = new TestSweetFrame(this);

		// Close the splash window.
		EventQueue.invokeLater(new SplashScreenCloser(splashScreen));
	}

	public LinkedList<Class< ? extends TestSweetTestCase>> getTestCases()
	{
		return _testClasses;
	}

	/**
	 * @see nl.sweet.testsweet.TestSweetListener#addTestSuiteResult(nl.sweet.testsweet.TestSweetResult)
	 */
	public void addTestSuiteResult(TestSweetResult testSuiteResult)
	{
		_testSweetResults.add(testSuiteResult);
		_testSweetFrame.addResultsContent(testSuiteResult.getTestCaseName(), testSuiteResult
				.isTestSuccesfull());
	}

	/**
	 * @see nl.sweet.testsweet.TestSweetListener#setAmountOfTests(int)
	 */
	public void setAmountOfTests(int totalTests)
	{
		_testSweetFrame.setTotalTests(totalTests);
	}

	/**
	 * @see nl.sweet.testsweet.TestSweetListener#setCurrentTest(int, java.lang.Class)
	 */
	public void setCurrentTest(int currentTest, Class< ? extends TestSweetTestCase> testClass)
	{
		_testSweetFrame.setProgressBarValue(currentTest);
		_testSweetFrame.setStatusText(testClass.toString());
	}

	/**
	 * @see nl.sweet.testsweet.TestSweetListener#setTotalTime(double)
	 */
	public void setTotalTime(double totalTime)
	{
		_totalTimeTaken = totalTime;
		_testSweetFrame.setDone();
	}

	/**
	 * Get the total time taken.
	 * @return The total time taken.
	 */
	public double getTotalTime()
	{
		return _totalTimeTaken;
	}

	/**
	 * Get the results.
	 * @return The results.
	 */
	public LinkedList<TestSweetResult> getTestSweetResults()
	{
		return _testSweetResults;
	}

	/**
	 * Class which is a runnable to close the splash screen.
	 * @author wessels
	 */
	private static final class SplashScreenCloser implements Runnable
	{
		/** The splash screen. */
		private TestSweetSplash _splashScreen;

		/**
		 * Contructor.
		 * @param splashScreen The slash screen to close.
		 */
		public SplashScreenCloser(TestSweetSplash splashScreen)
		{
			_splashScreen = splashScreen;
		}

		/**
		 * The run procedure which closes the splash screen. It will wait for 1 second to
		 * close it.
		 * @see java.lang.Runnable#run()
		 */
		public void run()
		{
			try
			{
				Thread.sleep(1000);
			}
			catch (InterruptedException e)
			{
				e.printStackTrace();
			}
			_splashScreen.dispose();
		}
	}
}
